home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / csv.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  13KB  |  427 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''
  5. csv.py - read/write/investigate CSV files
  6. '''
  7. import re
  8. from _csv import Error, __version__, writer, reader, register_dialect, unregister_dialect, get_dialect, list_dialects, field_size_limit, QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, __doc__
  9. from _csv import Dialect as _Dialect
  10.  
  11. try:
  12.     from cStringIO import StringIO
  13. except ImportError:
  14.     from StringIO import StringIO
  15.  
  16. __all__ = [
  17.     'QUOTE_MINIMAL',
  18.     'QUOTE_ALL',
  19.     'QUOTE_NONNUMERIC',
  20.     'QUOTE_NONE',
  21.     'Error',
  22.     'Dialect',
  23.     'excel',
  24.     'excel_tab',
  25.     'reader',
  26.     'writer',
  27.     'register_dialect',
  28.     'get_dialect',
  29.     'list_dialects',
  30.     'Sniffer',
  31.     'unregister_dialect',
  32.     '__version__',
  33.     'DictReader',
  34.     'DictWriter']
  35.  
  36. class Dialect:
  37.     '''Describe an Excel dialect.
  38.  
  39.     This must be subclassed (see csv.excel).  Valid attributes are:
  40.     delimiter, quotechar, escapechar, doublequote, skipinitialspace,
  41.     lineterminator, quoting.
  42.  
  43.     '''
  44.     _name = ''
  45.     _valid = False
  46.     delimiter = None
  47.     quotechar = None
  48.     escapechar = None
  49.     doublequote = None
  50.     skipinitialspace = None
  51.     lineterminator = None
  52.     quoting = None
  53.     
  54.     def __init__(self):
  55.         if self.__class__ != Dialect:
  56.             self._valid = True
  57.         
  58.         self._validate()
  59.  
  60.     
  61.     def _validate(self):
  62.         
  63.         try:
  64.             _Dialect(self)
  65.         except TypeError:
  66.             e = None
  67.             raise Error(str(e))
  68.  
  69.  
  70.  
  71.  
  72. class excel(Dialect):
  73.     '''Describe the usual properties of Excel-generated CSV files.'''
  74.     delimiter = ','
  75.     quotechar = '"'
  76.     doublequote = True
  77.     skipinitialspace = False
  78.     lineterminator = '\r\n'
  79.     quoting = QUOTE_MINIMAL
  80.  
  81. register_dialect('excel', excel)
  82.  
  83. class excel_tab(excel):
  84.     '''Describe the usual properties of Excel-generated TAB-delimited files.'''
  85.     delimiter = '\t'
  86.  
  87. register_dialect('excel-tab', excel_tab)
  88.  
  89. class DictReader:
  90.     
  91.     def __init__(self, f, fieldnames = None, restkey = None, restval = None, dialect = 'excel', *args, **kwds):
  92.         self.fieldnames = fieldnames
  93.         self.restkey = restkey
  94.         self.restval = restval
  95.         self.reader = reader(f, dialect, *args, **kwds)
  96.         self.dialect = dialect
  97.         self.line_num = 0
  98.  
  99.     
  100.     def __iter__(self):
  101.         return self
  102.  
  103.     
  104.     def next(self):
  105.         row = self.reader.next()
  106.         if self.fieldnames is None:
  107.             self.fieldnames = row
  108.             row = self.reader.next()
  109.         
  110.         self.line_num = self.reader.line_num
  111.         while row == []:
  112.             row = self.reader.next()
  113.         d = dict(zip(self.fieldnames, row))
  114.         lf = len(self.fieldnames)
  115.         lr = len(row)
  116.         if lf < lr:
  117.             d[self.restkey] = row[lf:]
  118.         elif lf > lr:
  119.             for key in self.fieldnames[lr:]:
  120.                 d[key] = self.restval
  121.             
  122.         
  123.         return d
  124.  
  125.  
  126.  
  127. class DictWriter:
  128.     
  129.     def __init__(self, f, fieldnames, restval = '', extrasaction = 'raise', dialect = 'excel', *args, **kwds):
  130.         self.fieldnames = fieldnames
  131.         self.restval = restval
  132.         if extrasaction.lower() not in ('raise', 'ignore'):
  133.             raise ValueError, "extrasaction (%s) must be 'raise' or 'ignore'" % extrasaction
  134.         
  135.         self.extrasaction = extrasaction
  136.         self.writer = writer(f, dialect, *args, **kwds)
  137.  
  138.     
  139.     def _dict_to_list(self, rowdict):
  140.         if self.extrasaction == 'raise':
  141.             for k in rowdict.keys():
  142.                 if k not in self.fieldnames:
  143.                     raise ValueError, 'dict contains fields not in fieldnames'
  144.                     continue
  145.             
  146.         
  147.         return [ rowdict.get(key, self.restval) for key in self.fieldnames ]
  148.  
  149.     
  150.     def writerow(self, rowdict):
  151.         return self.writer.writerow(self._dict_to_list(rowdict))
  152.  
  153.     
  154.     def writerows(self, rowdicts):
  155.         rows = []
  156.         for rowdict in rowdicts:
  157.             rows.append(self._dict_to_list(rowdict))
  158.         
  159.         return self.writer.writerows(rows)
  160.  
  161.  
  162.  
  163. try:
  164.     complex
  165. except NameError:
  166.     complex = float
  167.  
  168.  
  169. class Sniffer:
  170.     '''
  171.     "Sniffs" the format of a CSV file (i.e. delimiter, quotechar)
  172.     Returns a Dialect object.
  173.     '''
  174.     
  175.     def __init__(self):
  176.         self.preferred = [
  177.             ',',
  178.             '\t',
  179.             ';',
  180.             ' ',
  181.             ':']
  182.  
  183.     
  184.     def sniff(self, sample, delimiters = None):
  185.         '''
  186.         Returns a dialect (or None) corresponding to the sample
  187.         '''
  188.         (quotechar, delimiter, skipinitialspace) = self._guess_quote_and_delimiter(sample, delimiters)
  189.         if not delimiter:
  190.             (delimiter, skipinitialspace) = self._guess_delimiter(sample, delimiters)
  191.         
  192.         if not delimiter:
  193.             raise Error, 'Could not determine delimiter'
  194.         
  195.         
  196.         class dialect(Dialect):
  197.             _name = 'sniffed'
  198.             lineterminator = '\r\n'
  199.             quoting = QUOTE_MINIMAL
  200.             doublequote = False
  201.  
  202.         dialect.delimiter = delimiter
  203.         if not quotechar:
  204.             pass
  205.         dialect.quotechar = '"'
  206.         dialect.skipinitialspace = skipinitialspace
  207.         return dialect
  208.  
  209.     
  210.     def _guess_quote_and_delimiter(self, data, delimiters):
  211.         """
  212.         Looks for text enclosed between two identical quotes
  213.         (the probable quotechar) which are preceded and followed
  214.         by the same character (the probable delimiter).
  215.         For example:
  216.                          ,'some text',
  217.         The quote with the most wins, same with the delimiter.
  218.         If there is no quotechar the delimiter can't be determined
  219.         this way.
  220.         """
  221.         matches = []
  222.         for restr in ('(?P<delim>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\\w\n"\'])(?P<space> ?)', '(?P<delim>>[^\\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)', '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):
  223.             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
  224.             matches = regexp.findall(data)
  225.             if matches:
  226.                 break
  227.                 continue
  228.         
  229.         if not matches:
  230.             return ('', None, 0)
  231.         
  232.         quotes = { }
  233.         delims = { }
  234.         spaces = 0
  235.         for m in matches:
  236.             n = regexp.groupindex['quote'] - 1
  237.             key = m[n]
  238.             if key:
  239.                 quotes[key] = quotes.get(key, 0) + 1
  240.             
  241.             
  242.             try:
  243.                 n = regexp.groupindex['delim'] - 1
  244.                 key = m[n]
  245.             except KeyError:
  246.                 continue
  247.  
  248.             if key:
  249.                 if delimiters is None or key in delimiters:
  250.                     delims[key] = delims.get(key, 0) + 1
  251.                 
  252.             
  253.             try:
  254.                 n = regexp.groupindex['space'] - 1
  255.             except KeyError:
  256.                 continue
  257.  
  258.             if m[n]:
  259.                 spaces += 1
  260.                 continue
  261.         
  262.         quotechar = reduce((lambda a, b, quotes = quotes: if not quotes[a] > quotes[b] or a:
  263. passb), quotes.keys())
  264.         if delims:
  265.             delim = reduce((lambda a, b, delims = delims: if not delims[a] > delims[b] or a:
  266. passb), delims.keys())
  267.             skipinitialspace = delims[delim] == spaces
  268.             if delim == '\n':
  269.                 delim = ''
  270.             
  271.         else:
  272.             delim = ''
  273.             skipinitialspace = 0
  274.         return (quotechar, delim, skipinitialspace)
  275.  
  276.     
  277.     def _guess_delimiter(self, data, delimiters):
  278.         """
  279.         The delimiter /should/ occur the same number of times on
  280.         each row. However, due to malformed data, it may not. We don't want
  281.         an all or nothing approach, so we allow for small variations in this
  282.         number.
  283.           1) build a table of the frequency of each character on every line.
  284.           2) build a table of freqencies of this frequency (meta-frequency?),
  285.              e.g.  'x occurred 5 times in 10 rows, 6 times in 1000 rows,
  286.              7 times in 2 rows'
  287.           3) use the mode of the meta-frequency to determine the /expected/
  288.              frequency for that character
  289.           4) find out how often the character actually meets that goal
  290.           5) the character that best meets its goal is the delimiter
  291.         For performance reasons, the data is evaluated in chunks, so it can
  292.         try and evaluate the smallest portion of the data possible, evaluating
  293.         additional chunks as necessary.
  294.         """
  295.         data = filter(None, data.split('\n'))
  296.         ascii = [ chr(c) for c in range(127) ]
  297.         chunkLength = min(10, len(data))
  298.         iteration = 0
  299.         charFrequency = { }
  300.         modes = { }
  301.         delims = { }
  302.         start = 0
  303.         end = min(chunkLength, len(data))
  304.         while start < len(data):
  305.             iteration += 1
  306.             for line in data[start:end]:
  307.                 for char in ascii:
  308.                     metaFrequency = charFrequency.get(char, { })
  309.                     freq = line.count(char)
  310.                     metaFrequency[freq] = metaFrequency.get(freq, 0) + 1
  311.                     charFrequency[char] = metaFrequency
  312.                 
  313.             
  314.             for char in charFrequency.keys():
  315.                 items = charFrequency[char].items()
  316.                 if len(items) > 1:
  317.                     modes[char] = reduce((lambda a, b: if not a[1] > b[1] or a:
  318. passb), items)
  319.                     items.remove(modes[char])
  320.                     modes[char] = (modes[char][0], modes[char][1] - reduce((lambda a, b: (0, a[1] + b[1])), items)[1])
  321.                     continue
  322.                 None if len(items) == 1 and items[0][0] == 0 else []
  323.                 modes[char] = items[0]
  324.             
  325.             modeList = modes.items()
  326.             total = float(chunkLength * iteration)
  327.             consistency = 1
  328.             threshold = 0.9
  329.             while len(delims) == 0 and consistency >= threshold:
  330.                 for k, v in modeList:
  331.                     if v[0] > 0 and v[1] > 0:
  332.                         if v[1] / total >= consistency:
  333.                             pass
  334.                         None if delimiters is None or k in delimiters else k in delimiters
  335.                         continue
  336.                 
  337.                 consistency -= 0.01
  338.             if len(delims) == 1:
  339.                 delim = delims.keys()[0]
  340.                 skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  341.                 return (delim, skipinitialspace)
  342.             
  343.             start = end
  344.             end += chunkLength
  345.         if not delims:
  346.             return ('', 0)
  347.         
  348.         if len(delims) > 1:
  349.             for d in self.preferred:
  350.                 if d in delims.keys():
  351.                     skipinitialspace = data[0].count(d) == data[0].count('%c ' % d)
  352.                     return (d, skipinitialspace)
  353.                     continue
  354.             
  355.         
  356.         items = [ (v, k) for k, v in delims.items() ]
  357.         items.sort()
  358.         delim = items[-1][1]
  359.         skipinitialspace = data[0].count(delim) == data[0].count('%c ' % delim)
  360.         return (delim, skipinitialspace)
  361.  
  362.     
  363.     def has_header(self, sample):
  364.         rdr = reader(StringIO(sample), self.sniff(sample))
  365.         header = rdr.next()
  366.         columns = len(header)
  367.         columnTypes = { }
  368.         for i in range(columns):
  369.             columnTypes[i] = None
  370.         
  371.         checked = 0
  372.         for row in rdr:
  373.             if checked > 20:
  374.                 break
  375.             
  376.             checked += 1
  377.             if len(row) != columns:
  378.                 continue
  379.             
  380.             for col in columnTypes.keys():
  381.                 for thisType in [
  382.                     int,
  383.                     long,
  384.                     float,
  385.                     complex]:
  386.                     
  387.                     try:
  388.                         thisType(row[col])
  389.                     continue
  390.                     except (ValueError, OverflowError):
  391.                         continue
  392.                     
  393.  
  394.                 else:
  395.                     thisType = len(row[col])
  396.                 if thisType == long:
  397.                     thisType = int
  398.                 
  399.                 if thisType != columnTypes[col]:
  400.                     if columnTypes[col] is None:
  401.                         columnTypes[col] = thisType
  402.                     else:
  403.                         del columnTypes[col]
  404.                 columnTypes[col] is None
  405.             
  406.         
  407.         hasHeader = 0
  408.         for col, colType in columnTypes.items():
  409.             if type(colType) == type(0):
  410.                 if len(header[col]) != colType:
  411.                     hasHeader += 1
  412.                 else:
  413.                     hasHeader -= 1
  414.             len(header[col]) != colType
  415.             
  416.             try:
  417.                 colType(header[col])
  418.             except (ValueError, TypeError):
  419.                 hasHeader += 1
  420.                 continue
  421.  
  422.             hasHeader -= 1
  423.         
  424.         return hasHeader > 0
  425.  
  426.  
  427.